from fastapi import APIRouter,Depends, HTTPException
from sqlalchemy import and_
from sqlalchemy.exc import IntegrityError
from sqlalchemy.orm import Session
from database import get_db

from schemas.patient_schemas import PatientCreate, PatientUpdate
from schemas.doctor_schemas import DoctorCreate,DoctorUpdate
from schemas.pharmacist_schemas import PharmacistCreate,PharmacistUpdate
from schemas.worker_schemas import WorkerCreate,WorkerUpdate
from schemas.admin_schemas import AdminCreate,AdminUpdate



from services.auth_service import require_user
from services.password_service import hash_password,verify_password




from config import * #导入所有配置
from models.user_models import *


create_schemas_dict={
    UserType.PATIENT:PatientCreate,
    UserType.DOCTOR:DoctorCreate,
    UserType.PHARMACIST:PharmacistCreate,
    UserType.WORKER:WorkerCreate,
    UserType.ADMIN:AdminCreate
}

update_schemas_dict={
    UserType.PATIENT:PatientUpdate,
    UserType.DOCTOR:DoctorUpdate,
    UserType.PHARMACIST:PharmacistUpdate,
    UserType.WORKER:WorkerUpdate,
    UserType.ADMIN:AdminUpdate
}

model_class_dict={
    UserType.PATIENT:Patient,
    UserType.DOCTOR:Doctor,
    UserType.PHARMACIST:Pharmacist,
    UserType.WORKER:Worker,
    UserType.ADMIN:Admin
}



def get_all_users(user_type:UserType,db: Session):
    model_class=model_class_dict[user_type]

    try:
        people = db.query(model_class).all()
        return people
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

def get_user(user_type:UserType,db: Session,id:int):
    model_class=model_class_dict[user_type]
    try:
        person=db.query(model_class).filter_by(ID=id).first()
        if person is None:
            raise HTTPException(status_code=404, detail="User not found")
        return person
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

def create_user(user_type:UserType, db: Session,person):
    model_class=model_class_dict[user_type]
    create_schemas=create_schemas_dict[user_type]

    # 验证person的类型是否符合
    if not isinstance(person,create_schemas):
        raise HTTPException(status_code=400, detail=f"User {user_type.name} not supported")

    # 加密密码
    password_hash=hash_password(person.password)

    try:
        person.check()
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))

    try:
        with db.begin():
            # 插入 person 数据
            db_person = model_class.from_dict(person.model_dump())
            db.add(db_person)
            db.flush()  # 确保 person 被插入并获取 ID
            db.refresh(db_person)  # 刷新 db_person 的数据

            # 插入 account 数据
            db_account = Account(
                username=person.username,
                # password=person.password,
                password_hash=password_hash,
                user_type=user_type,
                user_ref_id=db_person.ID
            )
            db.add(db_account)  # 确保 account 被加入到 session
            db.flush()  # 确保 account 被插入
            db.refresh(db_account)  # 刷新 db_account 的数据


            return {
                "message": "User added successfully!",
                "user": db_person.to_dict(),
                "account": db_account.to_dict(),
            }

    except IntegrityError as e:
        db.rollback()
        if 'username' in str(e).lower():  # Check for unique constraint violation on username
            raise HTTPException(status_code=400, detail="用户名已存在！")
        raise HTTPException(status_code=400, detail="数据库约束错误")
    except Exception as e:
        db.rollback()
        raise HTTPException(status_code=400, detail=str(e))


def delete_user(user_type:UserType,db:Session,id:int):
    model_class = model_class_dict[user_type]

    try:
        with db.begin():
            db_person = db.query(model_class).filter_by(ID = id).first()
            if not db_person:
                raise HTTPException(status_code=404, detail=f"{user_type.name} not found")
            db.query(Account).filter(and_(Account.user_type == user_type,
                Account.user_ref_id == id)).delete()
            db.delete(db_person)
            return {"message": f"{user_type.name} deleted successfully!"}
    except Exception as e:
        db.rollback()
        raise HTTPException(status_code=400, detail=str(e))

def update_user(user_type:UserType,db:Session,person,id:int):
    model_class = model_class_dict[user_type]
    update_schemas = update_schemas_dict[user_type]

    # 验证person的类型是否符合
    if not isinstance(person, update_schemas):
        raise HTTPException(status_code=400, detail=f"User {user_type.name} not supported")

    # 检验数据是否合规
    try:
        person.check()
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))


    # 加密密码
    if person.password:
        password_hash=hash_password(person.password)
    else:
        password_hash=None

    try:
        with db.begin():
            db_person=db.query(model_class).filter_by(ID = id).first()
            db_account=db.query(Account).filter(and_(Account.user_type == user_type,Account.user_ref_id == id)).first()
            if not db_person:
                raise HTTPException(status_code=404, detail=f"{user_type.name} not found")
            if not db_account:
                raise HTTPException(status_code=404, detail="Account not found")

            person_dict = person.model_dump()

            if person_dict:
                db.query(model_class).filter_by(ID = id).update(
                    {key: value for key, value in person_dict.items() if
                     key in set(model_class.__table__.columns.keys()) and value is not None})


            account_update_data = {}
            if person_dict.get('username') is not None:
                account_update_data['username'] = person_dict['username']
            # if person_dict.get('password') is not None:
            #     account_update_data['password'] = person_dict['password']
            if password_hash is not None:
                account_update_data['password_hash'] = password_hash

            # 必须加if判断，否则如果为空会报错
            if account_update_data:
                db.query(Account).filter(and_(Account.user_type == user_type,
                                         Account.user_ref_id == id)).update(account_update_data)

            db.refresh(db_person)
            db.refresh(db_account)

            return {"message": f"{user_type.name} updated successfully!","account":db_account.to_dict(),"user":db_person.to_dict()}
    except Exception as e:
        print("出现异常了：", e)
        db.rollback()
        raise HTTPException(status_code=400, detail=str(e))


##以上的创建、更新、删除操作中都使用了事务管理，可以确保操作的原子性，防止并发操作导致的数据不一致问题，本后端中所有表的增删改都用到了事务管理